home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok77.lha
/
IFFlib
/
IFFlib.lha
/
Examples
/
GrabScreen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-14
|
8KB
|
341 lines
/*
**
** $Id: GrabScreen.c,v 21.2 92/05/18 02:27:41 chris Exp $
** $Revision: 21.2 $
**
** $Filename: Examples/GrabScreen.c $
** $Author: chris $
** $Release: 21.1 $
** $Date: 92/05/18 02:27:41 $
**
** IFF library example program. Compile with Lattice C 5.x.
** This program saves the contents of the frontmost screen as an IFF file
** with filename 'RAM:grabscreen.pic'.
** This example makes use of the IFFL_PushChunk() / IFFL_WriteChunkBytes() /
** IFFL_PopChunk() functions, it does not use IFFL_SaveBitMap().
**
** COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2,
** CH-8037 ZUERICH, SWITZERLAND.
** THIS FILE MAY BE FREELY DISTRIBUTED. USE AT YOUR OWN RISK.
**
*/
#include <proto/exec.h>
#include <exec/memory.h>
#include <proto/graphics.h>
#include <graphics/gfxbase.h>
#include <proto/intuition.h>
#include <intuition/intuitionbase.h>
#include <dos/dos.h>
#include <stdio.h>
#include <libraries/iff.h> /* IFF library include file */
/*
** Flags that should be masked out of old 16-bit CAMG before save or use.
** Note that 32-bit mode id (non-zero high word) bits should not be twiddled
*/
#define OLDCAMGMASK (~(SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO))
#define MAXSAVEDEPTH 24
#define BODYBUFSIZE 10000
#define MAXPACKEDSIZE(s) ((s)*2)
/*
** Masking techniques
*/
#define mskNone 0
#define mskHasMask 1
#define mskHasTransparentColor 2
#define mskLasso 3
/*
** Compression techniques
*/
#define cmpNone 0
#define cmpByteRun1 1
/****************************************************************************
** Globals
*/
struct Library *IFFBase;
char version[] = "\0$VER: GrabScreen 21.2 by Christian A. Weber";
/****************************************************************************
** This is an example implementation of an IFF writer. It writes the
** contents of a screen to an IFF ILBM file.
** Basically, this routine does the same as IFFL_SaveBitMap(), but it is
** here anyway to show you how to write an IFF file using iff.library's
** generic write functions.
*/
BOOL MySaveScreen(struct Screen *screen,char *filename)
{
IFFL_HANDLE iff;
struct BitMap *bitmap = &screen->BitMap;
BOOL result = FALSE;
/*
** Open the file for writing
*/
if(iff = IFFL_OpenIFF(filename,IFFL_MODE_WRITE))
{
struct IFFL_BMHD bmhd;
ULONG modeid;
UBYTE *colortable;
int count;
/*
** Prepare the BMHD structure
*/
bmhd.w = screen->Width;
bmhd.h = screen->Height;
bmhd.x = screen->LeftEdge; /* Not very useful :-) */
bmhd.y = screen->TopEdge;
bmhd.nPlanes = bitmap->Depth;
bmhd.masking = mskNone;
bmhd.compression = cmpByteRun1;
bmhd.pad1 = 0;
bmhd.transparentColor = 0;
bmhd.xAspect = screen->Width;
bmhd.yAspect = screen->Height;
bmhd.pageWidth = screen->Width;
bmhd.pageHeight = screen->Height;
/*
** Create the BMHD chunk. (goto considered useful :-))
*/
if(IFFL_PushChunk(iff,ID_ILBM,ID_BMHD))
{
if(!IFFL_WriteChunkBytes(iff,&bmhd,sizeof(bmhd)))
{
printf("Error writing BMHD data.\n");
goto error;
}
if(!IFFL_PopChunk(iff))
{
printf("Error closing BMHD chunk.\n");
goto error;
}
}
else
{
printf("Error creating BMHD chunk.\n");
goto error;
}
/*
** Create the CMAP chunk.
*/
count = screen->ViewPort.ColorMap->Count;
if(colortable = AllocMem(count * 3, MEMF_ANY))
{
int i;
for(i=0; i<count; ++i)
{
UWORD rgb4 = GetRGB4(screen->ViewPort.ColorMap,i);
colortable[i*3+0] = (rgb4 >> 4) & 0xF0;
colortable[i*3+0] |= colortable[i*3+0] >> 4;
colortable[i*3+1] = (rgb4 ) & 0xF0;
colortable[i*3+1] |= colortable[i*3+1] >> 4;
colortable[i*3+2] = (rgb4 << 4) & 0xF0;
colortable[i*3+2] |= colortable[i*3+2] >> 4;
}
if(IFFL_PushChunk(iff,ID_ILBM,ID_CMAP))
{
if(!IFFL_WriteChunkBytes(iff,colortable,count * 3))
{
printf("Error writing CMAP data.\n");
goto error;
}
if(!IFFL_PopChunk(iff))
{
printf("Error closing CMAP chunk.\n");
goto error;
}
}
else
{
printf("Error creating CMAP chunk.\n");
goto error;
}
FreeMem(colortable,count * 3);
}
/*
** Get the viewport's modes for the CAMG chunk.
*/
modeid = (GfxBase->LibNode.lib_Version >= 36) ?
GetVPModeID(&screen->ViewPort) : (screen->ViewPort.Modes&OLDCAMGMASK);
if(IFFL_PushChunk(iff,ID_ILBM,ID_CAMG))
{
if(!IFFL_WriteChunkBytes(iff,&modeid,sizeof(modeid)))
{
printf("Error writing CAMG data.\n");
goto error;
}
if(!IFFL_PopChunk(iff))
{
printf("Error closing CAMG chunk.\n");
goto error;
}
}
else
{
printf("Error creating CAMG chunk.\n");
goto error;
}
/*
** Generate BODY
*/
if(IFFL_PushChunk(iff,ID_ILBM,ID_BODY))
{
UBYTE *bodybuf;
if(bodybuf = AllocMem(BODYBUFSIZE,MEMF_ANY))
{
UBYTE *planes[MAXSAVEDEPTH];
int row,rowbytes,iplane,bodysize=0;
rowbytes = bitmap->BytesPerRow;
/*
** Copy the plane pointers into the local array "planes"
*/
for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
{
planes[iplane] = bitmap->Planes[iplane];
}
for(row=0; row < bmhd.h; ++row)
{
for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
{
int comprsize;
/*
** To speed up things, we collect as much data
** as possible in bodybuf before we write it out.
*/
if(bodysize > (BODYBUFSIZE-MAXPACKEDSIZE(rowbytes)))
{
if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
{
printf("Error writing BODY data.\n");
goto error;
}
bodysize = 0;
}
/*
** Compress the next row
*/
if(!(comprsize = IFFL_CompressBlock(planes[iplane],
bodybuf+bodysize,rowbytes,IFFL_COMPR_BYTERUN1)))
{
printf("Error compressing BODY data.\n");
goto error;
}
bodysize += comprsize;
planes[iplane] += rowbytes;
}
}
/*
** Now we're done, so flush the body data buffer
*/
if(bodysize)
{
if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
{
printf("Error writing BODY data.\n");
goto error;
}
}
FreeMem(bodybuf,BODYBUFSIZE);
}
else
{
printf("No memory for BODY buffer.\n");
goto error;
}
if(!IFFL_PopChunk(iff))
{
printf("Error closing BODY chunk.\n");
goto error;
}
/*
** If we get here, everything was fine.
*/
result = TRUE;
}
else
{
printf("Error creating BODY chunk.\n");
goto error;
}
error:
IFFL_CloseIFF(iff);
}
return result;
}
/****************************************************************************
** Main program
*/
int main(int argc, char **argv)
{
int result = RETURN_FAIL;
if(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))
{
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
{
/*
** For the new functions we need at least version 21 of iff.library.
*/
if(IFFBase = OpenLibrary(IFFNAME,21))
{
/*
** Note that we don't lock the screen, so it might go away while
** we're writing its contents to the file, and the picture may
** then contain garbage.
*/
MySaveScreen(IntuitionBase->FirstScreen,"RAM:grabscreen.pic");
result = RETURN_OK;
CloseLibrary(IFFBase);
}
else printf("Can't open iff.library V21+\n");
CloseLibrary(IntuitionBase);
}
else printf("Can't open intuition.library!\n");
CloseLibrary(GfxBase);
}
else printf("Can't open graphics.library!\n");
return result;
}